package com.chen.recruit.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.BetweenFormatter;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.chen.recruit.common.annotation.Log;
import com.chen.recruit.common.api.CommonResult;
import com.chen.recruit.common.constants.SysConstants;
import com.chen.recruit.common.enums.BusinessType;
import com.chen.recruit.common.enums.UserType;
import com.chen.recruit.domain.dto.OnlineUserDto;
import com.chen.recruit.domain.dto.UserDto;
import com.chen.recruit.domain.vo.OnlineUserVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotEmpty;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Api(tags = "在线用户监控 OnlineUserController")
@RestController
@RequestMapping("/monitor/online-user")
public class OnlineUserController {

    @ApiOperation("获取在线用户列表")
    @SaCheckPermission("monitor:online-user:list")
    @GetMapping("/list")
    public CommonResult list(OnlineUserVo vo) {
        List<OnlineUserDto> onlineUserDtoList = new ArrayList<>();
        List<String> keys = StpUtil.searchTokenValue("", -1, 0);
        for (String key : keys) {
            String token = key.replace(SysConstants.LOGIN_TOKEN_KEY, "");
            if (StpUtil.stpLogic.getTokenActivityTimeoutByToken(token) < 0) {
                StpUtil.kickoutByTokenValue(token);
                continue;
            }

            UserDto userDto = (UserDto) StpUtil.getTokenSessionByToken(token).get(SysConstants.LOGIN_USER);
            OnlineUserDto onlineUserDto = BeanUtil.toBean(userDto, OnlineUserDto.class);
            onlineUserDto.setOnlineTime(DateUtil.formatBetween(DateUtil.parse(DateUtil.now()),
                    userDto.getLoginTime(), BetweenFormatter.Level.MINUTE));
            onlineUserDtoList.add(onlineUserDto); //FIXME 在线时间，计算逻辑有问题
        }

        UserType type = vo.getType();
        String username = vo.getUsername();
        String name = vo.getName();

        if (ObjectUtil.isNotNull(type) && StringUtils.isNotBlank(username) && StringUtils.isNotBlank(name)) {
            onlineUserDtoList = onlineUserDtoList.stream()
                    .filter(onlineUserDto -> onlineUserDto.getType() == type
                            && onlineUserDto.getUsername().contains(username)
                            && onlineUserDto.getName().contains(name)).collect(Collectors.toList());
        }
        if (ObjectUtil.isNotNull(type)) {
            onlineUserDtoList = onlineUserDtoList.stream()
                    .filter(onlineUserDto -> onlineUserDto.getType() == type).collect(Collectors.toList());
        }
        if (StringUtils.isNotBlank(username)) {
            onlineUserDtoList = onlineUserDtoList.stream()
                    .filter(onlineUserDto -> onlineUserDto.getUsername().contains(username)).collect(Collectors.toList());
        }
        if (StringUtils.isNotBlank(name)) {
            onlineUserDtoList = onlineUserDtoList.stream()
                    .filter(onlineUserDto -> onlineUserDto.getName().contains(name)).collect(Collectors.toList());
        }

        return CommonResult.success(onlineUserDtoList);
    }

    @ApiOperation("强退用户")
    @SaCheckPermission("monitor:online-user:force")
    @DeleteMapping("/{ids}")
    @Log(module = "系统监控-在线用户", businessType = BusinessType.FORCE)
    public CommonResult forceLogout(@NotEmpty(message = "用户id不能为空") @PathVariable Integer[] ids) {
        for (Integer id : ids) {
            StpUtil.kickout(id);
        }
        return CommonResult.success();
    }

}
